package com.deliveryservicesystem.presentation.desktop.addpanel;

import com.deliveryservicesystem.app.exceptions.OutputError;
import com.deliveryservicesystem.app.exceptions.PreexistingEntityException;
import com.deliveryservicesystem.app.factory.AppFactory;
import com.deliveryservicesystem.app.util.AppUtils;
import com.deliveryservicesystem.app.validation.ProductValidator;
import com.deliveryservicesystem.app.validation.ValidationUtil;
import com.deliveryservicesystem.dataaccess.PersistenceDbManager;
import com.deliveryservicesystem.model.Product;
import com.deliveryservicesystem.model.Subscription;
import com.deliveryservicesystem.model.Supplier;
import com.deliveryservicesystem.presentation.desktop.InfoLableChangeHandler;
import com.deliveryservicesystem.presentation.desktop.MatchDialog;
import com.deliveryservicesystem.service.crud.impl.ProductCrudServiceImpl;
import com.jgoodies.validation.ValidationResult;
import com.jgoodies.validation.view.ValidationComponentUtils;
import com.jgoodies.validation.view.ValidationResultViewFactory;
import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.sql.SQLException;
import java.util.HashMap;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.JOptionPane;

/**
 * File Name: AddEditProductPanel.java
 * Version:
 * Description:
 * Package: com.deliveryservicesystem.presentation.desktop.addpanel
 * Author: Lance
 * Date: Jun 27, 2012
 * Editor:
 */
public class AddEditProductDialog extends javax.swing.JDialog
{

    private static final long serialVersionUID = 1L;
    private ProductCrudServiceImpl productCrudService;
    private Product productFromDb;
    private PersistenceDbManager dbManager;

    public AddEditProductDialog(java.awt.Frame parent, boolean modal, HashMap<String, String> values)
    {
        super(parent, modal);
        dbManager = PersistenceDbManager.getInstance();
        initComponents();
        cbSupplierNo.setSelectedIndex(-1);
        cbSubscriptionNo.setSelectedIndex(-1);
        productCrudService = new ProductCrudServiceImpl();
        if (!values.isEmpty())
        {
            cbSupplierNo.setSelectedItem(new Supplier(Integer.parseInt(values.get("SUPPLIER NUMBER"))));
            cbSubscriptionNo.setSelectedItem(new Subscription(Integer.parseInt(values.get("SUBSCRIPTION NUMBER"))));
            lblProdNo.setText(values.get("PRODUCT NUMBER"));
            txtProdPrice.setText(values.get("PRODUCT PRICE"));
            txtProdDesc.setText(values.get("PRODUCT DESCRIPTION"));
            productFromDb = productCrudService.findById(Integer.parseInt(values.get("PRODUCT NUMBER")));
        }

        ValidationComponentUtils.setInputHint(txtProdPrice, "Please enter a price. Must be numeric");
        ValidationComponentUtils.setInputHint(txtProdDesc, "Please enter a product description");
        ValidationComponentUtils.setInputHint(cbSupplierNo, "Please select a supplier number");
        ValidationComponentUtils.setInputHint(cbSubscriptionNo, "Please select a subscription number");

        KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(new InfoLableChangeHandler(lblInfo));
    }

    /**
     * This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        entityManager = dbManager.getEntityManager();
        supplierQuery = java.beans.Beans.isDesignTime() ? null : entityManager.createQuery("SELECT s FROM Supplier s");
        supplierList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : supplierQuery.getResultList();
        subscriptionQuery = java.beans.Beans.isDesignTime() ? null : entityManager.createQuery("SELECT s FROM Subscription s");
        subscriptionList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : subscriptionQuery.getResultList();
        lblInfo = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        lblValidationErrors = new javax.swing.JLabel();
        lblValidationErrors.setVisible(false);
        cbSupplierNo = new javax.swing.JComboBox();
        jLabel1 = new javax.swing.JLabel();
        cbSubscriptionNo = new javax.swing.JComboBox();
        lblProdNo = new javax.swing.JLabel();
        btnMatchSupplier = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        btnMatchSubscription = new javax.swing.JButton();
        txtProdPrice = new javax.swing.JTextField();
        btnCancel = new javax.swing.JButton();
        btnOk = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JSeparator();
        jLabel6 = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JSeparator();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtProdDesc = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        lblInfo.setIcon(ValidationResultViewFactory.getInfoIcon());
        lblInfo.setText("Info Lable");

        jLabel7.setText("Suppier Number");

        jLabel8.setText("Subscription Number");

        lblValidationErrors.setIcon(ValidationResultViewFactory.getCheckIcon());
        lblValidationErrors.setText("Validation Errors");

        cbSupplierNo.setRenderer(new DefaultListCellRenderer()
            {

                @Override
                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
                {
                    super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                    if (value instanceof Supplier)
                    {
                        Supplier supplier = (Supplier) value;
                        setText(supplier.getSupplierNo().toString());
                    }
                    return this;
                }
            });

            org.jdesktop.swingbinding.JComboBoxBinding jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, supplierList, cbSupplierNo, "supplierno");
            bindingGroup.addBinding(jComboBoxBinding);
            org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, supplierList, org.jdesktop.beansbinding.ObjectProperty.create(), cbSupplierNo, org.jdesktop.beansbinding.BeanProperty.create("selectedItem"), "supplier");
            bindingGroup.addBinding(binding);

            jLabel1.setText("Product Number");

            cbSubscriptionNo.setRenderer(new DefaultListCellRenderer()
                {

                    @Override
                    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
                    {
                        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                        if (value instanceof Subscription)
                        {
                            Subscription subscription = (Subscription) value;
                            setText(subscription.getSubscriptionNo().toString());
                        }
                        return this;
                    }
                });

                jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, subscriptionList, cbSubscriptionNo, "subscrip");
                bindingGroup.addBinding(jComboBoxBinding);
                binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, subscriptionList, org.jdesktop.beansbinding.ObjectProperty.create(), cbSubscriptionNo, org.jdesktop.beansbinding.BeanProperty.create("selectedItem"), "subscription");
                bindingGroup.addBinding(binding);

                lblProdNo.setText("New Number is Generated");

                btnMatchSupplier.setText("Match");
                btnMatchSupplier.addActionListener(new java.awt.event.ActionListener() {
                    public void actionPerformed(java.awt.event.ActionEvent evt) {
                        btnMatchSupplierActionPerformed(evt);
                    }
                });

                jLabel5.setText("Product Price");

                btnMatchSubscription.setText("Match");
                btnMatchSubscription.addActionListener(new java.awt.event.ActionListener() {
                    public void actionPerformed(java.awt.event.ActionEvent evt) {
                        btnMatchSubscriptionActionPerformed(evt);
                    }
                });

                btnCancel.setText("Cancel");
                btnCancel.addActionListener(new java.awt.event.ActionListener() {
                    public void actionPerformed(java.awt.event.ActionEvent evt) {
                        btnCancelActionPerformed(evt);
                    }
                });

                btnOk.setText("OK");
                btnOk.addActionListener(new java.awt.event.ActionListener() {
                    public void actionPerformed(java.awt.event.ActionEvent evt) {
                        btnOkActionPerformed(evt);
                    }
                });

                jLabel6.setText("Product Description");

                txtProdDesc.setColumns(20);
                txtProdDesc.setRows(5);
                jScrollPane1.setViewportView(txtProdDesc);

                javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
                getContentPane().setLayout(layout);
                layout.setHorizontalGroup(
                    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 550, Short.MAX_VALUE)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 550, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addGap(0, 0, Short.MAX_VALUE)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(lblInfo, javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                        .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(btnCancel))))
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(lblValidationErrors)
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(jLabel1)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(lblProdNo))
                                    .addGroup(layout.createSequentialGroup()
                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(jLabel6)
                                            .addComponent(jLabel8)
                                            .addComponent(jLabel7)
                                            .addComponent(jLabel5))
                                        .addGap(34, 34, 34)
                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 217, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addGroup(layout.createSequentialGroup()
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                                    .addComponent(cbSupplierNo, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                    .addComponent(txtProdPrice, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 137, Short.MAX_VALUE)
                                                    .addComponent(cbSubscriptionNo, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                    .addComponent(btnMatchSupplier)
                                                    .addComponent(btnMatchSubscription))))))
                                .addGap(0, 0, Short.MAX_VALUE)))
                        .addContainerGap())
                );
                layout.setVerticalGroup(
                    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1)
                            .addComponent(lblProdNo))
                        .addGap(9, 9, 9)
                        .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel5)
                            .addComponent(txtProdPrice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel6)
                                .addGap(149, 149, 149)
                                .addComponent(lblValidationErrors))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(18, 18, 18)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(jLabel7)
                                    .addComponent(cbSupplierNo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(btnMatchSupplier))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(jLabel8)
                                    .addComponent(cbSubscriptionNo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(btnMatchSubscription))))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 91, Short.MAX_VALUE)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(btnCancel)
                            .addComponent(btnOk))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblInfo)
                        .addContainerGap())
                );

                bindingGroup.bind();

                pack();
            }// </editor-fold>//GEN-END:initComponents

    private void btnMatchSupplierActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnMatchSupplierActionPerformed
    {//GEN-HEADEREND:event_btnMatchSupplierActionPerformed
        try
        {
            MatchDialog frame = new MatchDialog(null, true, "BEGIN ? := GET_DATA.SUPPLIERS; END;");
            AppUtils.locateOnScreenCenter(frame);
            frame.setVisible(true);
            cbSupplierNo.setSelectedItem(new Supplier(frame.getReturnStatus()));
        }
        catch (SQLException ex)
        {
            OutputError.toLog(ex);
            OutputError.toUser(ex);
        }
    }//GEN-LAST:event_btnMatchSupplierActionPerformed

    private void btnMatchSubscriptionActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnMatchSubscriptionActionPerformed
    {//GEN-HEADEREND:event_btnMatchSubscriptionActionPerformed
        try
        {
            MatchDialog frame = new MatchDialog(null, true, "BEGIN ? := GET_DATA.SUBSCRIPTIONS; END;");
            AppUtils.locateOnScreenCenter(frame);
            frame.setVisible(true);
            cbSubscriptionNo.setSelectedItem(new Subscription(frame.getReturnStatus()));
        }
        catch (SQLException ex)
        {
            OutputError.toLog(ex);
            OutputError.toUser(ex);
        }
    }//GEN-LAST:event_btnMatchSubscriptionActionPerformed

    private void btnCancelActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCancelActionPerformed
    {//GEN-HEADEREND:event_btnCancelActionPerformed
        if (AppUtils.askExitConfirm() == JOptionPane.YES_OPTION)
        {
            this.dispose();
        }
    }//GEN-LAST:event_btnCancelActionPerformed

    private void btnOkActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnOkActionPerformed
    {//GEN-HEADEREND:event_btnOkActionPerformed
        ProductValidator validator = new ProductValidator(txtProdPrice.getText(), txtProdDesc.getText(), cbSupplierNo.getSelectedItem(), cbSubscriptionNo.getSelectedItem());
        ValidationResult validationResult = validator.validate(new ValidationResult());
        ValidationUtil.displayErrorsToLable(validationResult, lblValidationErrors);

        if (validationResult.isEmpty())
        {
            String productPrice = txtProdPrice.getText();
            String productDesc = txtProdDesc.getText();
            String productNo = lblProdNo.getText();
            Supplier supplier = (Supplier) cbSupplierNo.getSelectedItem();
            Subscription subscription = (Subscription) cbSubscriptionNo.getSelectedItem();

            Product product = AppFactory.createProduct(productNo, productPrice, productDesc, supplier, subscription);

            int askUserQuestion = AppUtils.askUserQuestion(this, "Add/Edit the following?\n" + product, "Add/Edit", JOptionPane.YES_NO_CANCEL_OPTION);

            if (askUserQuestion == JOptionPane.YES_OPTION)
            {
                try
                {
                    if (product.getProductNo() == null)
                    {
                        productCrudService.create(product);
                        AppUtils.showUserMessage(this, "Added the following:\n" + product, "Add/Edit", JOptionPane.INFORMATION_MESSAGE);
                    }
                    else
                    {
                        AppFactory.createUpdatedProduct(product, productFromDb);
                        productCrudService.edit(productFromDb);
                        AppUtils.showUserMessage(this, "Updated the following:\n" + product, "Add/Edit", JOptionPane.INFORMATION_MESSAGE);
                    }
                    this.dispose();
                }
                catch (PreexistingEntityException ex)
                {
                    OutputError.toLog(ex);
                    OutputError.toUser(ex);
                }
                catch (Exception ex)
                {
                    OutputError.toLog(ex);
                    OutputError.toUser(ex);
                }
            }
        }
    }//GEN-LAST:event_btnOkActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCancel;
    private javax.swing.JButton btnMatchSubscription;
    private javax.swing.JButton btnMatchSupplier;
    private javax.swing.JButton btnOk;
    private javax.swing.JComboBox cbSubscriptionNo;
    private javax.swing.JComboBox cbSupplierNo;
    private javax.persistence.EntityManager entityManager;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JLabel lblInfo;
    private javax.swing.JLabel lblProdNo;
    private javax.swing.JLabel lblValidationErrors;
    private java.util.List<com.deliveryservicesystem.model.Subscription> subscriptionList;
    private javax.persistence.Query subscriptionQuery;
    private java.util.List<com.deliveryservicesystem.model.Supplier> supplierList;
    private javax.persistence.Query supplierQuery;
    private javax.swing.JTextArea txtProdDesc;
    private javax.swing.JTextField txtProdPrice;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
}
